home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 52369 / 52369.xpi / content / script-compiler.js < prev    next >
Text File  |  2009-11-30  |  7KB  |  247 lines

  1. var betterfacebook_gmCompiler={
  2.  
  3. // getUrlContents adapted from Greasemonkey Compiler
  4. // http://www.letitblog.com/code/python/greasemonkey.py.txt
  5. // used under GPL permission
  6. //
  7. // most everything else below based heavily off of Greasemonkey
  8. // http://greasemonkey.devjavu.com/
  9. // used under GPL permission
  10.  
  11. getUrlContents: function(aUrl){
  12.     var    ioService=Components.classes["@mozilla.org/network/io-service;1"]
  13.         .getService(Components.interfaces.nsIIOService);
  14.     var    scriptableStream=Components
  15.         .classes["@mozilla.org/scriptableinputstream;1"]
  16.         .getService(Components.interfaces.nsIScriptableInputStream);
  17.     var unicodeConverter=Components
  18.         .classes["@mozilla.org/intl/scriptableunicodeconverter"]
  19.         .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  20.     unicodeConverter.charset="UTF-8";
  21.  
  22.     var    channel=ioService.newChannel(aUrl, null, null);
  23.     var    input=channel.open();
  24.     scriptableStream.init(input);
  25.     var    str=scriptableStream.read(input.available());
  26.     scriptableStream.close();
  27.     input.close();
  28.  
  29.     try {
  30.         return unicodeConverter.ConvertToUnicode(str);
  31.     } catch (e) {
  32.         return str;
  33.     }
  34. },
  35.  
  36. isGreasemonkeyable: function(url) {
  37.     var scheme=Components.classes["@mozilla.org/network/io-service;1"]
  38.         .getService(Components.interfaces.nsIIOService)
  39.         .extractScheme(url);
  40.     return (
  41.         (scheme == "http" || scheme == "https" || scheme == "file") &&
  42.         !/hiddenWindow\.html$/.test(url)
  43.     );
  44. },
  45.  
  46. contentLoad: function(e) {
  47.     var unsafeWin=e.target.defaultView;
  48.     if (unsafeWin.wrappedJSObject) unsafeWin=unsafeWin.wrappedJSObject;
  49.  
  50.     var unsafeLoc=new XPCNativeWrapper(unsafeWin, "location").location;
  51.     var href=new XPCNativeWrapper(unsafeLoc, "href").href;
  52.  
  53.     if (
  54.         betterfacebook_gmCompiler.isGreasemonkeyable(href)
  55.         && ( /http:\/\/www\.facebook\.com\/.*/.test(href) )
  56.         && true
  57.     ) {
  58.         var script=betterfacebook_gmCompiler.getUrlContents(
  59.             'chrome://betterfacebook/content/betterfacebook.js'
  60.         );
  61.         betterfacebook_gmCompiler.injectScript(script, href, unsafeWin);
  62.     }
  63. },
  64.  
  65. injectScript: function(script, url, unsafeContentWin) {
  66.     var sandbox, script, logger, storage, xmlhttpRequester;
  67.     var safeWin=new XPCNativeWrapper(unsafeContentWin);
  68.  
  69.     sandbox=new Components.utils.Sandbox(safeWin);
  70.  
  71.     var storage=new betterfacebook_ScriptStorage();
  72.     xmlhttpRequester=new betterfacebook_xmlhttpRequester(
  73.         unsafeContentWin, window//appSvc.hiddenDOMWindow
  74.     );
  75.  
  76.     sandbox.window=safeWin;
  77.     sandbox.document=sandbox.window.document;
  78.     sandbox.unsafeWindow=unsafeContentWin;
  79.  
  80.     // patch missing properties on xpcnw
  81.     sandbox.XPathResult=Components.interfaces.nsIDOMXPathResult;
  82.  
  83.     // add our own APIs
  84.     sandbox.GM_addStyle=function(css) { betterfacebook_gmCompiler.addStyle(sandbox.document, css) };
  85.     sandbox.GM_setValue=betterfacebook_gmCompiler.hitch(storage, "setValue");
  86.     sandbox.GM_getValue=betterfacebook_gmCompiler.hitch(storage, "getValue");
  87.     sandbox.GM_openInTab=betterfacebook_gmCompiler.hitch(this, "openInTab", unsafeContentWin);
  88.     sandbox.GM_xmlhttpRequest=betterfacebook_gmCompiler.hitch(
  89.         xmlhttpRequester, "contentStartRequest"
  90.     );
  91.     //unsupported
  92.     sandbox.GM_registerMenuCommand=function(){};
  93.     sandbox.GM_log=function(){};
  94.     sandbox.GM_getResourceURL=function(){};
  95.     sandbox.GM_getResourceText=function(){};
  96.  
  97.     sandbox.isExtension = true;
  98.  
  99.     sandbox.__proto__=sandbox.window;
  100.  
  101.     try {
  102.         this.evalInSandbox(
  103.             "(function(){"+script+"})()",
  104.             url,
  105.             sandbox);
  106.     } catch (e) {
  107.         var e2=new Error(typeof e=="string" ? e : e.message);
  108.         e2.fileName=script.filename;
  109.         e2.lineNumber=0;
  110.         //GM_logError(e2);
  111.         alert(e2);
  112.     }
  113. },
  114.  
  115. evalInSandbox: function(code, codebase, sandbox) {
  116.     if (Components.utils && Components.utils.Sandbox) {
  117.         // DP beta+
  118.         Components.utils.evalInSandbox(code, sandbox);
  119.     } else if (Components.utils && Components.utils.evalInSandbox) {
  120.         // DP alphas
  121.         Components.utils.evalInSandbox(code, codebase, sandbox);
  122.     } else if (Sandbox) {
  123.         // 1.0.x
  124.         evalInSandbox(code, sandbox, codebase);
  125.     } else {
  126.         throw new Error("Could not create sandbox.");
  127.     }
  128. },
  129.  
  130. openInTab: function(unsafeContentWin, url) {
  131.     var tabBrowser = getBrowser(), browser, isMyWindow = false;
  132.     for (var i = 0; browser = tabBrowser.browsers[i]; i++)
  133.         if (browser.contentWindow == unsafeContentWin) {
  134.             isMyWindow = true;
  135.             break;
  136.         }
  137.     if (!isMyWindow) return;
  138.  
  139.     var loadInBackground, sendReferrer, referrer = null;
  140.     loadInBackground = tabBrowser.mPrefs.getBoolPref("browser.tabs.loadInBackground");
  141.     sendReferrer = tabBrowser.mPrefs.getIntPref("network.http.sendRefererHeader");
  142.     if (sendReferrer) {
  143.         var ios = Components.classes["@mozilla.org/network/io-service;1"]
  144.                             .getService(Components.interfaces.nsIIOService);
  145.         referrer = ios.newURI(content.document.location.href, null, null);
  146.      }
  147.      tabBrowser.loadOneTab(url, referrer, null, null, loadInBackground);
  148.  },
  149.  
  150.  hitch: function(obj, meth) {
  151.     var unsafeTop = new XPCNativeWrapper(unsafeContentWin, "top").top;
  152.  
  153.     for (var i = 0; i < this.browserWindows.length; i++) {
  154.         this.browserWindows[i].openInTab(unsafeTop, url);
  155.     }
  156. },
  157.  
  158. apiLeakCheck: function(allowedCaller) {
  159.     var stack=Components.stack;
  160.  
  161.     var leaked=false;
  162.     do {
  163.         if (2==stack.language) {
  164.             if ('chrome'!=stack.filename.substr(0, 6) &&
  165.                 allowedCaller!=stack.filename 
  166.             ) {
  167.                 leaked=true;
  168.                 break;
  169.             }
  170.         }
  171.  
  172.         stack=stack.caller;
  173.     } while (stack);
  174.  
  175.     return leaked;
  176. },
  177.  
  178. hitch: function(obj, meth) {
  179.     if (!obj[meth]) {
  180.         throw "method '" + meth + "' does not exist on object '" + obj + "'";
  181.     }
  182.  
  183.     var hitchCaller=Components.stack.caller.filename;
  184.     var staticArgs = Array.prototype.splice.call(arguments, 2, arguments.length);
  185.  
  186.     return function() {
  187.         if (betterfacebook_gmCompiler.apiLeakCheck(hitchCaller)) {
  188.             return;
  189.         }
  190.         
  191.         // make a copy of staticArgs (don't modify it because it gets reused for
  192.         // every invocation).
  193.         var args = staticArgs.concat();
  194.  
  195.         // add all the new arguments
  196.         for (var i = 0; i < arguments.length; i++) {
  197.             args.push(arguments[i]);
  198.         }
  199.  
  200.         // invoke the original function with the correct this obj and the combined
  201.         // list of static and dynamic arguments.
  202.         return obj[meth].apply(obj, args);
  203.     };
  204. },
  205.  
  206. addStyle:function(doc, css) {
  207.     var head, style;
  208.     head = doc.getElementsByTagName('head')[0];
  209.     if (!head) { return; }
  210.     style = doc.createElement('style');
  211.     style.type = 'text/css';
  212.     style.innerHTML = css;
  213.     head.appendChild(style);
  214. },
  215.  
  216. onLoad: function() {
  217.     var    appcontent=window.document.getElementById("appcontent");
  218.     if (appcontent && !appcontent.greased_betterfacebook_gmCompiler) {
  219.         appcontent.greased_betterfacebook_gmCompiler=true;
  220.         appcontent.addEventListener("DOMContentLoaded", betterfacebook_gmCompiler.contentLoad, false);
  221.     }
  222. },
  223.  
  224. onUnLoad: function() {
  225.     //remove now unnecessary listeners
  226.     window.removeEventListener('load', betterfacebook_gmCompiler.onLoad, false);
  227.     window.removeEventListener('unload', betterfacebook_gmCompiler.onUnLoad, false);
  228.     window.document.getElementById("appcontent")
  229.         .removeEventListener("DOMContentLoaded", betterfacebook_gmCompiler.contentLoad, false);
  230. },
  231.  
  232. }; //object betterfacebook_gmCompiler
  233.  
  234.  
  235. function betterfacebook_ScriptStorage() {
  236.     this.prefMan=new betterfacebook_PrefManager();
  237. }
  238. betterfacebook_ScriptStorage.prototype.setValue = function(name, val) {
  239.     this.prefMan.setValue(name, val);
  240. }
  241. betterfacebook_ScriptStorage.prototype.getValue = function(name, defVal) {
  242.     return this.prefMan.getValue(name, defVal);
  243. }
  244.  
  245.  
  246. window.addEventListener('load', betterfacebook_gmCompiler.onLoad, false);
  247. window.addEventListener('unload', betterfacebook_gmCompiler.onUnLoad, false);